package com.xy.exam.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * 安全配置类 - 简化版
 */
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final UserDetailsService userDetailsService;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 禁用CSRF保护（JWT不需要）
            .csrf(AbstractHttpConfigurer::disable)
            
            // 请求授权配置
            .authorizeHttpRequests(auth -> auth
                // 允许公开访问的API
                .requestMatchers(
                    "/api/auth/**",  // 认证API
                    "/",             // 首页
                    "/css/**",       // 静态资源
                    "/js/**",
                    "/images/**"
                ).permitAll()
                // 其他所有请求需要认证
                .anyRequest().authenticated()
            )
            
            // 异常处理
            .exceptionHandling(exceptions -> exceptions
                .authenticationEntryPoint((request, response, authException) -> {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(401);
                    response.getWriter().write("{\"code\":401,\"message\":\"请先登录\",\"success\":false}");
                })
            )
            
            // 使用无状态会话（JWT不需要会话）
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            
            // 添加JWT过滤器
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

// 使用@Bean注解标记该方法，将其返回的对象注册为Spring容器中的一个Bean
    @Bean
// 定义一个名为authenticationManager的方法，该方法接收一个AuthenticationConfiguration类型的参数config
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
    // 调用config对象的getAuthenticationManager方法，获取AuthenticationManager实例
    // AuthenticationManager是Spring Security中用于认证的核心接口
        return config.getAuthenticationManager();
    }

    @Bean
// 定义一个Spring Bean，该Bean会被Spring容器管理
    public DaoAuthenticationProvider authenticationProvider() {
    // 创建一个DaoAuthenticationProvider对象，用于提供基于数据库的用户认证服务
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    // 设置用户详细信息服务，用于加载用户特定数据
        provider.setUserDetailsService(userDetailsService);
    // 设置密码编码器，用于对用户输入的密码进行编码和匹配
        provider.setPasswordEncoder(passwordEncoder());
    // 返回配置好的DaoAuthenticationProvider对象
        return provider;
    }

    @Bean

    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
} 